昨天開始評估如何從 GitLab CI/CD Pipelines 轉移至 GitHub Actions,我們過去是採用「runner 在 container 內、job 也在獨立的 container 內執行」的執行模式,如果 GitHub 有一樣的模式可以照搬,那就可以省很多功夫在 porting 上。
我評估了一下,執行 CI/CD job 的方式若以「是否採用容器化技術」來做區別的話,有 4 種組合:
run:
) 給弄亂今天先來玩看看 3.,也就是讓 job 執行於另一個 container 內。
這需要寫一個新的 workflow,如果還要設定 self-hosted runner 有點麻煩,我先使用 GitHub 提供的 runner 來執行我的 workflow,等 workflow 確定準備好後再改用 self-hosted runner 來執行。
先建立一個簡單的 .NET 6.0 專案,盡量貼近公司的 tech stack。此 solution 包含一個 library、一個 unit test suite、一個 app:
其中 workflow 定義如下:
name: .NET Core CI/CD in Container
on:
push:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
container:
image: mcr.microsoft.com/dotnet/sdk:6.0
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Restore dependencies
run: dotnet restore
- name: Build solution
run: dotnet build --configuration Release --no-restore
- name: Run unit tests
run: dotnet test --no-restore --verbosity normal
- name: Publish console app
run: dotnet publish MyConsoleApp/MyConsoleApp.csproj --configuration Release --no-build --output ./publish/
- name: Upload artifact
uses: actions/upload-artifact@v3
with:
name: MyConsoleApp
path: ./publish/
validate:
needs: build
runs-on: ubuntu-latest
steps:
- name: Download artifact
uses: actions/download-artifact@v3
with:
name: MyConsoleApp
path: ./publish
- name: Check current working directory
run: pwd
- name: List files in current working directory
run: ls -la
- name: Try running the console app
run: |
chmod +x ./publish/MyConsoleApp
./publish/MyConsoleApp
包含兩個 job:build
和 validate
。
build
作業:dotnet restore
以還原 NuGet 套件。dotnet build
以建置整個解決方案。dotnet test
以執行單元測試。dotnet publish
以發佈控制台應用程式。validate
作業:actions/download-artifact@v2
來下載 build
作業中創建的 artifact。chmod +x
來給予應用程式執行權限,然後執行它。這個工作流程能夠在同一個容器環境中自動建置、測試、發佈,並驗證 .NET 解決方案。它首先建置和測試解決方案,然後發佈控制台應用程式並作為 artifact 上傳。之後,它會下載這個 artifact 並跑起來,以確保它可以正確執行。
廢話不多說,直接上。
來看 build
流程,可以看到有 Initializa containers
還有 'Stop containers` 兩個 step
Upload artifact
可以看到成功上傳了我們 build 出來的東西:
Run actions/upload-artifact@v3
with:
name: MyConsoleApp
path: ./publish/
if-no-files-found: warn
/usr/bin/docker exec b63...ea20 sh -c "cat /etc/*release | grep ^ID"
With the provided path, there will be 7 files uploaded
Starting artifact upload
For more detailed logs during the artifact upload process, enable step-debugging: https://docs.github.com/actions/monitoring-and-troubleshooting-workflows/enabling-debug-logging#enabling-step-debug-logging
Artifact name is valid!
Container for artifact "MyConsoleApp" successfully created. Starting upload of file(s)
Total size of all the files uploaded is 70402 bytes
File upload process has finished. Finalizing the artifact upload
Artifact has been finalized. All files have been successfully uploaded!
The raw size of all the files that were specified for upload is 173101 bytes
The size of all the files that were uploaded is 70402 bytes. This takes into account any gzip compression used to reduce the upload size, time and storage
Note: The size of downloaded zips can differ significantly from the reported size. For more information see: https://github.com/actions/upload-artifact#zipped-artifact-downloads
Artifact MyConsoleApp has been successfully uploaded!
![[Pasted image 20230921224436.png]]
來看 validate
job,由於只是要跑程式而已,此 job 就未使用 container 了。
Download artifact
可以看到有下載 artifact 的行為
Run actions/download-artifact@v3
with:
name: MyConsoleApp
path: ./publish
Starting download for MyConsoleApp
Directory structure has been setup for the artifact
Total number of files that will be downloaded: 7
Artifact MyConsoleApp was downloaded to /home/runner/work/dotnet-cicd-eval/dotnet-cicd-eval/publish
Artifact download has finished successfully
Try running the console app
輸出了我們剛剛建置的 app 的內容!
Run chmod +x ./publish/MyConsoleApp
Addition: 2 + 3 = 5
Subtraction: 3 - 2 = 1
今天的實驗證明 runner 是可以在 container 內執行並且上傳 artifact 作為其他用途。這個 artifact 也可以用來給 infra team 部署到正式環境用。
就這個 workflow 就做了一個小時,累了 XD。
明天我們再來看一下是否能在 self-hosted runner 執行這個 workflow。